# -*- codeing = utf-8 -*-
# @Time : 2021/2/28 10:58
# @Atuthor: 朱朱
# @File: 154可迭代对象.py
# @Software: PyCharm
""
"""
迭代是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问，
直到所有的元素被访问完结束。迭代器只能往前不会后退。
那么也就是说，一个具备了__iter__方法的对象，就是一个可迭代对象。

一个实现了iter方法和next方法的对象，就是迭代器。
迭代器自身正是一个迭代器，所以迭代器的__iter__方法返回自身即可。
return self

调用一个对象的__iter__方法，或者调用iter()内置函数，可以获取到一个可迭代对象的迭代器。
可以使用 isinstance() 判断一个对象是否是 Iterator 对象：
"""
# 有很多可迭代对象:  list/tuple/dict/set/str/range/filter/map
# for...in 可迭代对象

from collections.abc import Iterable
class Demo(object):
    def __init__(self,x):
        self.x = x
        self.count = 0

    def __iter__(self): # 重写了iter,是一个可迭代对象
        return self

    def __next__(self):
        # 每一次for in 循环,都会调用一次next方法,获取返回值
        """
        i = 0,时,调用这里,self.count = 1,< 10,返回1-1 = 0
        i = 1,时,调用这里,self.count = 2,< 10,返回2-1 = 1
        :return:
        """
        self.count +=1 # 如果没有这个,会出现死循环,一直打印
        if self.count <= self.x:
            return self.count -1 # 0-9
            # return self.count # 1 2 3 4 5 6 7 8 9
        else:
            raise StopIteration # 停止迭代

d = Demo(10)
print(type(d)) # <class '__main__.Demo'>
# isinstance:用来判断一个实例对象是否是有指定的类创建出来的
print(isinstance(d, Iterable)) # 用来判断,是否是一个可迭代对象
print(d)    # <__main__.Demo object at 0x00000219E0C38DC8>
x = d.__iter__()
print(x is d) # true 同一个对象

# for...in循环的本质就调用可迭代对象的 __iter__ 方法，获取到这个方法的返回值
# 这个返回值需要是一个对象，然后再调用这个对象 __next__ 方法
for i in d:
    print(i ,end=' ')

print('------------------------')
p = Demo(8)
i = p.__iter__()
# print(i.__next__())


x = iter(p)
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x)) # 7
print(next(x)) # raise StopIteration # 停止迭代 超出下标了
